mod common;
use chrono::prelude::*;
use common::{dourl, eq_obj_notime};
use serde_json::json;
use std::{file, line};
use std::{thread, time};

#[tokio::test]
async fn a_chunk() {
    let data = json!({
        "db": "other",
        "n": "chunk"
    });
    let ret = dourl(&data, "rmtab").await.expect("error_1");
    assert_eq!(ret, json!({"code": 1000, "fail": false, "success": true}));

    let data = json!({
        "db": "other",
        "tab": "chunk",
        "line": "line-one",
        "data": [
            {
                "psn": "p1001",
                "wsn": "w001",
                "k": {
                    "esn": "e001",
                },
                "v": {
                    "d1":11,
                    "d2":21,
                    "d3":21,
                }
            }
        ]
    });
    let ret = dourl(&data, "chunk").await.expect("error_3");
    assert_eq!(ret, json!({"code": 1000, "fail": false, "success": true}));

    let data = json!({
        "db": "other",
        "n": "chunk",
        "obj": "*",
    });
    let mut ret = dourl(&data, "get").await.expect("error_4");
    eq_obj_notime(
        &mut ret,
        json!({
            "code": 1000,
            "success": true,
            "fail": false,
            "data": {
                "chunk": {"data": [
                    {"d1": 11, "d2": 21, "d3": 21, "esn": "e001", "line": "line-one", "psn": "p1001", "wsn": "w001", "dtp": 0},
                ]}
            }
        }),
        line!(),
        file!(),
    );

    let data = json!({
        "db": "other",
        "n": "chunk",
        "tm": true,
        "obj": "*",
    });
    let ret = dourl(&data, "get").await.expect("error_5");
    let ret = ret
        .as_object()
        .unwrap()
        .get("data")
        .unwrap()
        .as_object()
        .unwrap()
        .get("chunk")
        .unwrap()
        .as_object()
        .unwrap()
        .get("data")
        .unwrap()
        .as_array()
        .unwrap();
    let ret = &ret[0];
    let ret = ret.as_object().unwrap();
    let tm = ret.get("time").unwrap().as_str().unwrap();
    let ti = ret.get("ti").unwrap().as_str().unwrap();

    let data = json!({
        "db": "other",
        "n": "chunk",
        "data": [{
            "tm": tm.to_string(),
            "k": {
                "line": "line-one",
                "psn": "p1001",
                "wsn": "w001",
                "esn": "e001",
                "ti": ti.to_string()
            },
            "v": {
                "d1": 111
            }
        }]
    });
    let ret = dourl(&data, "md").await.expect("error_6");
    assert_eq!(ret, json!({"code": 1000, "fail": false, "success": true}));

    let data = json!({
        "db": "other",
        "n": "chunk",
        "obj": "*",
    });
    let mut ret = dourl(&data, "get").await.expect("error_4");
    eq_obj_notime(
        &mut ret,
        json!({
            "code": 1000,
            "success": true,
            "fail": false,
            "data": {
                "chunk": {"data": [
                    {"d1": 111, "d2": 21, "d3": 21, "esn": "e001", "line": "line-one", "psn": "p1001", "wsn": "w001", "dtp": 0},
                ]}
            }
        }),
        line!(),
        file!(),
    );

    let data = json!({
        "db": "other",
        "n": "chunk",
        "data": [{
            "tm": tm.to_string(),
            "k": {
                "line": "line-one",
                "psn": "p1001",
                "wsn": "w001",
                "esn": "e001",
                "ti": ti.to_string()
            },
            "v": {
                "dtp": 2000
            }
        }]
    });
    let ret = dourl(&data, "md").await.expect("error_6");
    assert_eq!(ret, json!({"code": 1000, "fail": false, "success": true}));

    let data = json!({
        "db": "other",
        "n": "chunk",
        "dtp": false,
        "obj": "*",
    });
    let mut ret = dourl(&data, "get").await.expect("error_14");
    eq_obj_notime(
        &mut ret,
        json!({
            "code": 1000,
            "success": true,
            "fail": false,
            "data": {
                "chunk": {"data": [
                    {"dtp": 2000, "d1": 111, "d2": 21, "d3": 21, "esn": "e001", "line": "line-one", "psn": "p1001", "wsn": "w001"},
                ]}
            }
        }),
        line!(),
        file!(),
    );

    let data = json!({
        "db": "other",
        "n": "chunk",
        "dtp": false,
        "obj": "d1,d2",
    });
    let mut ret = dourl(&data, "get").await.expect("error_14");
    eq_obj_notime(
        &mut ret,
        json!({
            "code": 1000,
            "success": true,
            "fail": false,
            "data": {
                "chunk": {"data": [
                    {"dtp": 2000, "d1": 111, "d2": 21},
                ]}
            }
        }),
        line!(),
        file!(),
    );

    let data = json!({
        "db": "other",
        "n": "chunk",
        "obj": "*",
    });
    let ret = dourl(&data, "get").await.expect_err("error_4");
    assert_eq!(
        ret,
        json!({
            "code": 2500,
            "fail": true,
            "success": false,
            "message": r#"data empty error: "no data""#,
        })
    );

    let data = json!({
        "db": "other",
        "n": "chunk",
        "obj": "d1,d2",
    });
    let ret = dourl(&data, "get").await.expect_err("error_4");
    assert_eq!(
        ret,
        json!({
            "code": 2500,
            "fail": true,
            "success": false,
            "message": r#"data empty error: "no data""#,
        })
    );

    let data = json!({
        "db": "other",
        "n": "chunk",
        "data": [{
            "tm": tm.to_string(),
            "k": {
                "line": "line-one",
                "psn": "p1001",
                "wsn": "w001",
                "esn": "e001",
                "ti": ti.to_string()
            },
            "v": {
                "dtp": 10
            }
        }]
    });
    let ret = dourl(&data, "md").await.expect("error_16");
    assert_eq!(ret, json!({"code": 1000, "fail": false, "success": true}));

    let data = json!({
        "db": "other",
        "n": "chunk",
        "obj": "*",
    });
    let mut ret = dourl(&data, "get").await.expect("error_14");
    eq_obj_notime(
        &mut ret,
        json!({
            "code": 1000,
            "success": true,
            "fail": false,
            "data": {
                "chunk": {"data": [
                    {"dtp": 10, "d1": 111, "d2": 21, "d3": 21, "esn": "e001", "line": "line-one", "psn": "p1001", "wsn": "w001"},
                ]}
            }
        }),
        line!(),
        file!(),
    );
}

#[tokio::test]
async fn b_chunk() {
    let data = json!({
        "db": "other",
        "n": "chunk,chunk1"
    });
    let ret = dourl(&data, "rmtab").await.expect("error_1");
    assert_eq!(ret, json!({"code": 1000, "fail": false, "success": true}));

    let data = json!({
        "db": "other",
        "tab": "chunk",
        "line": "line-one",
        "data": [
            {
                "psn": "p1001",
                "wsn": "w001",
                "k": {
                    "esn": "e001",
                },
                "v": {
                    "d1":11,
                    "d2":21,
                    "d3":21,
                }
            }
        ]
    });
    let ret = dourl(&data, "chunk").await.expect("error_3");
    assert_eq!(ret, json!({"code": 1000, "fail": false, "success": true}));

    let data = json!({
        "db": "other",
        "n": "chunk",
        "obj": "*",
    });
    let mut ret = dourl(&data, "get").await.expect("error_4");
    eq_obj_notime(
        &mut ret,
        json!({
            "code": 1000,
            "success": true,
            "fail": false,
            "data": {
                "chunk": {"data": [
                    {"d1": 11, "d2": 21, "d3": 21, "esn": "e001", "line": "line-one", "psn": "p1001", "wsn": "w001", "dtp": 0},
                ]}
            }
        }),
        line!(),
        file!(),
    );

    let data = json!({
        "db": "other",
        "tab": "chunk1",
        "line": "line-one",
        "data": [
            {
                "psn": "p1001",
                "wsn": "w001",
                "k": {
                    "esn": "e001",
                },
                "v": {
                    "d1":11,
                    "d2":21,
                    "d3":21,
                }
            }
        ]
    });
    let ret = dourl(&data, "chunk").await.expect("error_3");
    assert_eq!(ret, json!({"code": 1000, "fail": false, "success": true}));

    let data = json!({
        "db": "other",
        "n": "chunk1",
        "obj": "*",
    });
    let mut ret = dourl(&data, "get").await.expect("error_4");
    eq_obj_notime(
        &mut ret,
        json!({
            "code": 1000,
            "success": true,
            "fail": false,
            "data": {
                "chunk1": {"data": [
                    {"d1": 11, "d2": 21, "d3": 21, "esn": "e001", "line": "line-one", "psn": "p1001", "wsn": "w001", "dtp": 0},
                ]}
            }
        }),
        line!(),
        file!(),
    );

    let data = json!({
        "db": "other",
        "n": "chunk",
        "tm": true,
        "obj": "*",
    });
    let ret = dourl(&data, "get").await.expect("error_5");
    let ret = ret
        .as_object()
        .unwrap()
        .get("data")
        .unwrap()
        .as_object()
        .unwrap()
        .get("chunk")
        .unwrap()
        .as_object()
        .unwrap()
        .get("data")
        .unwrap()
        .as_array()
        .unwrap();
    let ret = &ret[0];
    let ret = ret.as_object().unwrap();
    let tm = ret.get("time").unwrap().as_str().unwrap();
    let ti = ret.get("ti").unwrap().as_str().unwrap();

    let data = json!({
        "db": "other",
        "n": "chunk1",
        "tm": true,
        "obj": "*",
    });
    let ret = dourl(&data, "get").await.expect("error_5");
    let ret = ret
        .as_object()
        .unwrap()
        .get("data")
        .unwrap()
        .as_object()
        .unwrap()
        .get("chunk1")
        .unwrap()
        .as_object()
        .unwrap()
        .get("data")
        .unwrap()
        .as_array()
        .unwrap();
    let ret = &ret[0];
    let ret = ret.as_object().unwrap();
    let tm1 = ret.get("time").unwrap().as_str().unwrap();
    let ti1 = ret.get("ti").unwrap().as_str().unwrap();

    let data = json!({
    "db": "other",
    "chunk": [
    {
        "n": "chunk",
        "data": [{
            "tm": tm.to_string(),
            "k": {
                "line": "line-one",
                "psn": "p1001",
                "wsn": "w001",
                "esn": "e001",
                "ti": ti.to_string()
            },
            "v": {
                "d1": 111
            }
        }]
    },
    {
        "n": "chunk1",
        "data": [{
            "tm": tm1.to_string(),
            "k": {
                "line": "line-one",
                "psn": "p1001",
                "wsn": "w001",
                "esn": "e001",
                "ti": ti1.to_string()
            },
            "v": {
                "d1": 111
            }
        }]
    },
    ]});
    let ret = dourl(&data, "mdchunk").await.expect("error_6");
    assert_eq!(ret, json!({"code": 1000, "fail": false, "success": true}));

    let data = json!({
        "db": "other",
        "n": "chunk",
        "obj": "*",
    });
    let mut ret = dourl(&data, "get").await.expect("error_4");
    eq_obj_notime(
        &mut ret,
        json!({
            "code": 1000,
            "success": true,
            "fail": false,
            "data": {
                "chunk": {"data": [
                    {"d1": 111, "d2": 21, "d3": 21, "esn": "e001", "line": "line-one", "psn": "p1001", "wsn": "w001", "dtp": 0},
                ]},
            }
        }),
        line!(),
        file!(),
    );

    let data = json!({
        "db": "other",
        "n": "chunk1",
        "obj": "*",
    });
    let mut ret = dourl(&data, "get").await.expect("error_4");
    eq_obj_notime(
        &mut ret,
        json!({
            "code": 1000,
            "success": true,
            "fail": false,
            "data": {
                "chunk1": {"data": [
                    {"d1": 111, "d2": 21, "d3": 21, "esn": "e001", "line": "line-one", "psn": "p1001", "wsn": "w001", "dtp": 0},
                ]},
            }
        }),
        line!(),
        file!(),
    );
}

#[tokio::test]
async fn c_rm() {
    let data = json!({
        "db": "other",
        "n": "rmtest"
    });
    let ret = dourl(&data, "rmtab").await.expect("error_1");
    assert_eq!(ret, json!({"code": 1000, "fail": false, "success": true}));

    let diff = time::Duration::from_millis(1000);

    let data = json!({
        "db": "other",
        "tab": "rmtest",
        "line": "line-one",
        "data": [
            {
                "psn": "p1001",
                "wsn": "w001",
                "k": {
                    "esn": "e001",
                },
                "v": {
                    "d1":11,
                    "d2":21,
                    "d3":21,
                }
            },
        ]
    });
    let ret = dourl(&data, "chunk").await.expect("error_3");
    assert_eq!(ret, json!({"code": 1000, "fail": false, "success": true}));

    thread::sleep(diff);

    let data = json!({
        "db": "other",
        "tab": "rmtest",
        "line": "line-one",
        "data": [
            {
                "psn": "p1002",
                "wsn": "w001",
                "k": {
                    "esn": "e001",
                },
                "v": {
                    "d1":11,
                    "d2":21,
                    "d3":21,
                }
            },
        ]
    });
    let ret = dourl(&data, "chunk").await.expect("error_3");
    assert_eq!(ret, json!({"code": 1000, "fail": false, "success": true}));

    thread::sleep(diff);

    let local: DateTime<Local> = Local::now();
    let local = local.format("%Y-%m-%dT%H:%M:%SZ").to_string();

    let data = json!({
        "db": "other",
        "tab": "rmtest",
        "line": "line-one",
        "data": [
            {
                "psn": "p1003",
                "wsn": "w001",
                "k": {
                    "esn": "e001",
                },
                "v": {
                    "d1":11,
                    "d2":21,
                    "d3":21,
                }
            },
        ]
    });
    let ret = dourl(&data, "chunk").await.expect("error_3");
    assert_eq!(ret, json!({"code": 1000, "fail": false, "success": true}));

    let data = json!({
        "db": "other",
        "n": "rmtest",
        "obj": "*",
    });
    let mut ret = dourl(&data, "get").await.expect("error_4");
    eq_obj_notime(
        &mut ret,
        json!({
            "code": 1000,
            "success": true,
            "fail": false,
            "data": {
                "rmtest": {"data": [
                    {"d1": 11, "d2": 21, "d3": 21, "esn": "e001", "line": "line-one", "psn": "p1001", "wsn": "w001", "dtp": 0},
                    {"d1": 11, "d2": 21, "d3": 21, "esn": "e001", "line": "line-one", "psn": "p1002", "wsn": "w001", "dtp": 0},
                    {"d1": 11, "d2": 21, "d3": 21, "esn": "e001", "line": "line-one", "psn": "p1003", "wsn": "w001", "dtp": 0},
                ]},
            }
        }),
        line!(),
        file!(),
    );

    let data = json!({
        "db": "other",
        "n": "rmtest",
        "time": local,
        "utc": 8,
        "opt": "lt"
    });
    let ret = dourl(&data, "rm").await.expect("error_4");
    assert_eq!(ret, json!({"code": 1000, "fail": false, "success": true}));

    let data = json!({
        "db": "other",
        "n": "rmtest",
        "obj": "*",
    });
    let mut ret = dourl(&data, "get").await.expect("error_4");
    eq_obj_notime(
        &mut ret,
        json!({
            "code": 1000,
            "success": true,
            "fail": false,
            "data": {
                "rmtest": {"data": [
                    {"d1": 11, "d2": 21, "d3": 21, "esn": "e001", "line": "line-one", "psn": "p1003", "wsn": "w001", "dtp": 0},
                ]},
            }
        }),
        line!(),
        file!(),
    );
}
